TOP_MODULE	:= $(strip $(TOP))
SRCS		:= $(TOP_MODULE).sv

# 检查 TOP_MODULE 是否已定义
ifneq ($(MAKECMDGOALS), clean)
	ifndef TOP_MODULE
	$(error TOP_MODULE is not defined.)
	endif
endif

# 支持的仿真工具
SUPPORTED_SIM_TOOLS := vcs vivado modelsim questasim xcelium

# 仿真工具, 默认为 vcs
SIM_TOOL ?= vcs

# 检查用户指定的 SIM_TOOL 是否在支持的工具列表中
ifneq ($(filter $(SIM_TOOL), $(SUPPORTED_SIM_TOOLS)), $(SIM_TOOL))
  $(error Invalid SIM_TOOL '$(SIM_TOOL)'. Supported tools are: $(SUPPORTED_SIM_TOOLS))
endif

# 根据仿真工具设置编译和仿真命令
# 使用 vcs
ifeq ($(SIM_TOOL), vcs)
	LIB_COMMAND		:=
	COMPILE_COMMAND	:= vcs -full64 -sverilog -debug_access+all -top $(TOP_MODULE) $(SRCS)
	ELAB_COMMAND	:=
	SIM_COMMAND		:= ./simv -l sim.log
endif
ifeq ($(SIM_TOOL), xcelium)
	LIB_COMMAND		:=
	COMPILE_COMMAND	:= xrun -compile $(SRCS)
	ELAB_COMMAND	:= xrun -elaborate $(SRCS)
	SIM_COMMAND		:= xrun -R -l sim.log
endif
# 使用 vivado
ifeq ($(SIM_TOOL), vivado)
	LIB_COMMAND		:=
	COMPILE_COMMAND	:= xvlog -sv $(SRCS)
	ELAB_COMMAND	:= xelab -top $(TOP_MODULE) -snapshot $(TOP_MODULE).sim
	SIM_COMMAND		:= xsim $(TOP_MODULE).sim -runall -log sim.log
endif
# 使用 modelsim 或 questasim
ifneq ($(filter modelsim questasim, $(SIM_TOOL)),)
	LIB_COMMAND		:= vlib work
	COMPILE_COMMAND	:= vlog -sv -work work +incdir+. $(SRCS)
	ELAB_COMMAND	:=
	SIM_COMMAND		:= vsim -c -do "run -all; quit" work.$(TOP_MODULE) -l sim.log
endif

.PHONY: all pre sim clean

all: sim

# 准备
pre:
	@echo "Compiling with $(SIM_TOOL)..."
	$(LIB_COMMAND)
	$(COMPILE_COMMAND)
	$(ELAB_COMMAND)
	@echo "Compilation finished."

# 仿真
sim: pre
	@echo "Running simulation with $(SIM_TOOL)..."
	$(SIM_COMMAND)
	@echo "Simulation finished."

# 清理
clean:
	rm -rf simv* csrc *.vpd *.vcd *.log ucli.key work xsim* webtalk* xelab* xvlog* .Xil vc_hdrs.h xrun.* xcelium.d
